from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
import time
import os
import platform
from selenium.common.exceptions import TimeoutException
import json


# 每次运行脚本时重置 hotels_data.json 文件
asset_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "asset")
hotels_json_path = os.path.join(asset_dir, "hotels_data.json")
with open(hotels_json_path, "w", encoding="utf-8") as f:
    json.dump([], f, ensure_ascii=False, indent=2)


def parse_and_save_hotel_cards(hotel_cards, processed_hotel_ids, json_file_path):
    """
    解析hotel_cards并实时追加写入hotels_data.json，去重。
    """
    import json as json_lib
    import os
    # 读取已有数据
    if os.path.exists(json_file_path):
        with open(json_file_path, "r", encoding="utf-8") as f:
            try:
                hotels_data = json_lib.load(f)
            except Exception:
                hotels_data = []
    else:
        hotels_data = []
    existing_ids = {h["id"] for h in hotels_data}
    new_hotels = []
    for card in hotel_cards:
        try:
            hotel_id = "未知ID"
            try:
                data_exposure = card.get_attribute("data-exposure")
                if data_exposure:
                    exposure_data = json_lib.loads(data_exposure)
                    if "data" in exposure_data and "masterhotelid" in exposure_data["data"]:
                        hotel_id = exposure_data["data"]["masterhotelid"]
            except Exception:
                pass
            if hotel_id in processed_hotel_ids or hotel_id in existing_ids:
                continue
            processed_hotel_ids.add(hotel_id)
            hotel_name_element = card.find_element(By.CLASS_NAME, "hotelName")
            hotel_name = hotel_name_element.text
            img_elements = card.find_elements(By.CSS_SELECTOR, ".m-lazyImg__img")
            hotel_images = [img.get_attribute("src") for img in img_elements if img.get_attribute("src") and img.get_attribute("src").startswith("http")]
            try:
                score_element = card.find_element(By.CLASS_NAME, "score")
                hotel_score = score_element.text
            except:
                hotel_score = "暂无评分"
            try:
                position_element = card.find_element(By.CLASS_NAME, "position-desc")
                hotel_position = position_element.text
            except:
                hotel_position = "位置信息暂无"
            try:
                price_element = card.find_element(By.CLASS_NAME, "sale")
                hotel_price = price_element.text
            except:
                hotel_price = "价格暂无"
            hotel_info = {
                "id": hotel_id,
                "name": hotel_name,
                "images": hotel_images,
                "score": hotel_score,
                "position": hotel_position,
                "price": hotel_price
            }
            new_hotels.append(hotel_info)
            print(f"已提取酒店: {hotel_name} (ID: {hotel_id})")
        except Exception as e:
            print(f"提取酒店信息时出错: {e}")
            continue
    if new_hotels:
        hotels_data.extend(new_hotels)
        with open(json_file_path, "w", encoding="utf-8") as f:
            json_lib.dump(hotels_data, f, ensure_ascii=False, indent=2)
        print(f"已追加写入{len(new_hotels)}条酒店数据到: {json_file_path}")

def get_hotel_list():
  
    chrome_options = Options()
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")
    chrome_options.add_argument("--disable-web-security")
    chrome_options.add_argument("--allow-running-insecure-content")
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_experimental_option('useAutomationExtension', False)
        
    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=chrome_options)
         # 执行反检测脚本
    driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
    url="https://hotels.ctrip.com/hotels/listPage?cityename=hangzhou&city=17&optionId=17&optionType=City&checkin=2025/07/18&checkout=2025/07/19"
    try:
        # 清理可能损坏的ChromeDriver缓存
        try:
            chromedriver_path = ChromeDriverManager().install()
            print(f"ChromeDriverManager返回路径: {chromedriver_path}")
            
            # 修复路径问题：ChromeDriverManager有时返回错误的文件
            if platform.system() == "Windows":
                # 查找正确的chromedriver.exe文件
                driver_dir = os.path.dirname(chromedriver_path)
                possible_paths = [
                    os.path.join(driver_dir, "chromedriver.exe"),
                    os.path.join(driver_dir, "chromedriver-win32", "chromedriver.exe"),
                    os.path.join(os.path.dirname(driver_dir), "chromedriver.exe"),
                    chromedriver_path if chromedriver_path.endswith(".exe") else None
                ]
                
                actual_driver_path = None
                for path in possible_paths:
                    if path and os.path.exists(path) and path.endswith(".exe"):
                        file_size = os.path.getsize(path)
                        if file_size > 1000:  # 确保文件不是空的或损坏的
                            actual_driver_path = path
                            print(f"找到有效的ChromeDriver: {actual_driver_path} (大小: {file_size} bytes)")
                            break
                
                if not actual_driver_path:
                    raise Exception("未找到有效的chromedriver.exe文件")
                
                chromedriver_path = actual_driver_path
            
            # 检查文件是否存在且可执行
            if not os.path.exists(chromedriver_path):
                raise Exception("ChromeDriver文件不存在")
            
            service = Service(chromedriver_path)
            print(f"使用ChromeDriver: {chromedriver_path}")
            
        except Exception as driver_error:
            print(f"ChromeDriver安装/检查失败: {driver_error}")
            print("尝试使用系统PATH中的chromedriver...")
            service = Service()  # 使用系统PATH中的chromedriver
        
        driver = webdriver.Chrome(service=service, options=chrome_options)
        
        # 先访问主页以设置域名
        driver.get("https://www.ctrip.com")
        
        # 加载cookies
        cookies_file = os.path.join(os.path.dirname(os.path.dirname(__file__)), "asset", "cookies.json")
        if os.path.exists(cookies_file):
            with open(cookies_file, "r", encoding="utf-8") as f:
                cookies = json.load(f)
            
            for cookie in cookies:
                try:
                    # 移除可能导致问题的字段
                    cookie_to_add = {
                        'name': cookie['name'],
                        'value': cookie['value'],
                        'domain': cookie['domain'],
                        'path': cookie['path']
                    }
                    
                    # 添加可选字段
                    if 'expiry' in cookie:
                        cookie_to_add['expiry'] = cookie['expiry']
                    if 'httpOnly' in cookie:
                        cookie_to_add['httpOnly'] = cookie['httpOnly']
                    if 'secure' in cookie:
                        cookie_to_add['secure'] = cookie['secure']
                    if 'sameSite' in cookie:
                        cookie_to_add['sameSite'] = cookie['sameSite']
                    
                    driver.add_cookie(cookie_to_add)
                    print(f"已添加cookie: {cookie['name']}")
                except Exception as e:
                    print(f"添加cookie {cookie['name']} 失败: {e}")
                    continue
            
            print("Cookies加载完成")
        else:
            print("未找到cookies文件")
        
        # 现在访问目标页面
        driver.get(url)
        
        # 等待页面加载完成
        wait = WebDriverWait(driver, 10)
        wait.until(EC.presence_of_element_located((By.CLASS_NAME, "hotel-card")))
        
        # 无限滚动加载所有数据
        hotels_data = []
        processed_hotel_ids = set()  # 用于去重
        asset_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "asset")
        if not os.path.exists(asset_dir):
            os.makedirs(asset_dir)
        json_file_path = os.path.join(asset_dir, "hotels_data.json")
        last_hotel_count = 0
        no_new_data_count = 0
        max_no_new_data_attempts = 5
        print("开始滚动加载酒店数据...")
        while True:
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            time.sleep(1)
            try:
                more_btn = driver.find_element(By.XPATH, "//div[contains(@class, 'list-btn-more')]//span[contains(text(), '搜索更多酒店')]")
                if more_btn.is_displayed() and more_btn.is_enabled():
                    driver.execute_script("arguments[0].click();", more_btn)
                    print("点击了搜索更多酒店按钮")
                    time.sleep(2)
            except Exception:
                pass
            hotel_cards = driver.find_elements(By.CLASS_NAME, "hotel-card")
            current_hotel_count = len(hotel_cards)
            print(f"当前页面酒店数量: {current_hotel_count}")
            parse_and_save_hotel_cards(hotel_cards, processed_hotel_ids, json_file_path)
            if current_hotel_count == last_hotel_count:
                no_new_data_count += 1
                print(f"没有新数据加载 ({no_new_data_count}/{max_no_new_data_attempts})")
                if no_new_data_count >= max_no_new_data_attempts:
                    print("连续多次没有新数据，停止加载")
                    break
            else:
                no_new_data_count = 0
                last_hotel_count = current_hotel_count
            try:
                load_more_btn = driver.find_element(By.XPATH, "//button[contains(text(), '加载更多')] | //div[contains(text(), '加载更多')] | //span[contains(text(), '加载更多')]")
                if load_more_btn.is_displayed() and load_more_btn.is_enabled():
                    driver.execute_script("arguments[0].click();", load_more_btn)
                    print("点击了加载更多按钮")
                    time.sleep(2)
            except:
                pass
        print("滚动加载完成")
        return hotels_data
    except TimeoutException:
        print("等待超时，可能未完成短信验证或页面未跳转。")
        return None
    except Exception as e:
        print(f"发生错误: {str(e)}")
        return None
    finally:
        if driver:
            driver.quit()
            print("浏览器已关闭")


# 用法示例：
if __name__ == '__main__':
    # get_hotel_list()
    print("获取酒店列表请求打开get_host_list()注释")



